package com.zxt.content.copywriting.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zxt.content.common.Bean.BUserInfoApiVO;
import com.zxt.content.common.exception.ServiceException;
import com.zxt.content.common.utils.*;
import com.zxt.content.copywriting.enums.CopywritingStatusEnum;
import com.zxt.content.copywriting.events.CopywritingEventPublisher;
import com.zxt.content.copywriting.manager.CopywritingTypeManager;
import com.zxt.content.copywriting.manager.CopywritingTypeRelationManager;
import com.zxt.content.copywriting.manager.PrivateCopywritingManager;
import com.zxt.content.copywriting.model.CopywritingType;
import com.zxt.content.copywriting.model.CopywritingTypeRelation;
import com.zxt.content.copywriting.model.PrivateCopywriting;
import com.zxt.content.copywriting.req.CopywritingTypeRelationDTO;
import com.zxt.content.copywriting.req.PrivateCopywritingDTO;
import com.zxt.content.copywriting.req.PrivateCopywritingQueryDTO;
import com.zxt.content.copywriting.resp.PrivateCopywritingVO;
import com.zxt.content.copywriting.service.IPrivateCopywritingService;
import com.zxt.content.copywriting.events.upload.UploadCopywritingEventContext;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 私有文案模块业务逻辑层
 *
 * @author zxt
 */
@Service(value = "privateCopywritingService")
@AllArgsConstructor
@Slf4j
public class PrivateCopywritingServiceImpl implements IPrivateCopywritingService {

    private final PrivateCopywritingManager privateCopywritingManager;
    private final CopywritingTypeManager copywritingTypeManager;
    private final CopywritingTypeRelationManager copywritingTypeRelationManager;

    private final CopywritingEventPublisher copywritingEventPublisher;


    @Override
    public List<PrivateCopywritingVO> queryList() {
        return ZXTBeanUtils.beanCopy(privateCopywritingManager.list(), PrivateCopywritingVO.class);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Long saveOrEdit(PrivateCopywritingDTO dto) {
        //从ThreadLocal里取出当前登录的用户信息
        BUserInfoApiVO userInfoApiVO = UserContainer.USER_INFO_VO_THREAD_LOCAL.get();
        dto.setUserId(userInfoApiVO.getId());
        //1.校验私有文案主题是否存在
        List<PrivateCopywriting> themes = privateCopywritingManager.themesList(dto);
        if (ZXTCollectionsUtil.isNotEmpty(themes)) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "文案主题[" + dto.getTheme() + "]已存在,请勿重复添加!");
        }
        if (dto.getContent().contains("\"")) {
            //去掉非法符合
            dto.setContent(dto.getContent().replaceAll("\"", "'"));
        }
        //2.判断文案的类型是否存在
        List<CopywritingType> types = copywritingTypeManager.typesList(dto.getTypeIds());
        int size = dto.getTypeIds().size();
        if (Objects.isNull(types) || types.size() != size) {
            throw new ServiceException(ResultCode.COMMON_MESSAGE, "类型不存在,操作失败");
        }
        if (Objects.isNull(dto.getId())) {
            dto.setUserId(userInfoApiVO.getId());
            dto.setCopywritingStatus(CopywritingStatusEnum.NOT_UPLOADE.getValue());
            PrivateCopywriting privateCopywriting = ZXTBeanUtils.beanCopy(dto, PrivateCopywriting.class);
            privateCopywritingManager.save(privateCopywriting);

            CopywritingTypeRelationDTO copywritingTypeRelationDTO = new CopywritingTypeRelationDTO();
            copywritingTypeRelationDTO.setCopywritingId(privateCopywriting.getId());
            copywritingTypeRelationDTO.setTypeIds(dto.getTypeIds());
            copywritingTypeRelationDTO.setIsPublic(Boolean.FALSE);
            save(copywritingTypeRelationDTO);
            return privateCopywriting.getId();
        } else {
            List<PrivateCopywriting> list = privateCopywritingManager.copywritersList(dto);
            if (!Objects.isNull(list)) {
                throw new ServiceException(ResultCode.COMMON_MESSAGE, "同一用户下文案主题不能存在多个!");
            }
            privateCopywritingManager.updateById(ZXTBeanUtils.beanCopy(dto, PrivateCopywriting.class));
            CopywritingTypeRelationDTO copywritingTypeRelationDTO = new CopywritingTypeRelationDTO();
            copywritingTypeRelationDTO.setCopywritingId(dto.getId());
            copywritingTypeRelationDTO.setTypeIds(dto.getTypeIds());
            copywritingTypeRelationDTO.setIsPublic(Boolean.FALSE);
            update(copywritingTypeRelationDTO);
            return dto.getId();
        }
    }

    @Override
    public Page<PrivateCopywritingVO> pageList(PrivateCopywritingQueryDTO privateCopywritingDTO) {
        //从ThreadLocal里取出当前登录的用户信息
        BUserInfoApiVO userInfoApiVO = UserContainer.USER_INFO_VO_THREAD_LOCAL.get();
        privateCopywritingDTO.setUserId(userInfoApiVO.getId());
        List<Long> copywritingId = new ArrayList<>();
        if (ZXTCollectionsUtil.isNotEmpty(privateCopywritingDTO.getTypeIds())) {
            List<CopywritingTypeRelation> typeRelations = copywritingTypeRelationManager.typeRelationsList(privateCopywritingDTO.getTypeIds());
            copywritingId = typeRelations.stream().map(CopywritingTypeRelation::getCopywritingId).distinct().collect(Collectors.toList());
        }
        Page<PrivateCopywriting> page = new Page<>(privateCopywritingDTO.getPage(), privateCopywritingDTO.getPageSize());
        Page<PrivateCopywriting> copywritingPage = privateCopywritingManager.pageList(page, privateCopywritingDTO, copywritingId);
        List<PrivateCopywriting> records = copywritingPage.getRecords();

        Page<PrivateCopywritingVO> privateCopywritingVOPage = new Page<>(privateCopywritingDTO.getPage(), privateCopywritingDTO.getPageSize());
        privateCopywritingVOPage.setTotal(page.getTotal());
        if (ZXTCollectionsUtil.isEmpty(records)) {
            privateCopywritingVOPage.setRecords(Collections.emptyList());
            return privateCopywritingVOPage;
        }
        List<PrivateCopywritingVO> privateCopywritingVOS = records.stream().map(item -> ZXTBeanUtils.beanCopy(item, PrivateCopywritingVO.class)).collect(Collectors.toList());
        privateCopywritingVOPage.setRecords(privateCopywritingVOS);
        return privateCopywritingVOPage;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchDelete(List<Long> ids) {
        privateCopywritingManager.removeByIds(ids);
        copywritingTypeRelationManager.deleteByIds(ids);
    }

    @Override
    public void uploadCopywriting(List<Long> ids) {
        //获取当前用户信息
        BUserInfoApiVO userInfoApiVO = UserContainer.USER_INFO_VO_THREAD_LOCAL.get();
        //简称事件上下文，跨越整个事件
        UploadCopywritingEventContext eventContext = UploadCopywritingEventContext.builder().userInfoApiVO(userInfoApiVO).copywritingIds(ids).build();

        try {
            String result = copywritingEventPublisher.uploadCopywriting(eventContext);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw e;
        }
    }


    public void save(CopywritingTypeRelationDTO dto) {
        List<CopywritingTypeRelation> relationList = new ArrayList<>();
        for (Long aLong : dto.getTypeIds()) {
            CopywritingTypeRelation typeRelation = new CopywritingTypeRelation();
            typeRelation.setCopywritingId(dto.getCopywritingId());
            typeRelation.setIsPublic(dto.getIsPublic());
            typeRelation.setTypeId(aLong);
            relationList.add(typeRelation);
        }
        copywritingTypeRelationManager.saveBatch(relationList);
    }

    public void update(CopywritingTypeRelationDTO dto) {
        copywritingTypeRelationManager.delete(dto);

        List<CopywritingTypeRelation> relationList = new ArrayList<>();
        for (Long aLong : dto.getTypeIds()) {
            CopywritingTypeRelation typeRelation = new CopywritingTypeRelation();
            typeRelation.setCopywritingId(dto.getCopywritingId());
            typeRelation.setIsPublic(dto.getIsPublic());
            typeRelation.setTypeId(aLong);
            relationList.add(typeRelation);
        }
        copywritingTypeRelationManager.saveBatch(relationList);
    }
}
